home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / dev / lang / python020.lha / python / lib / dis.py < prev    next >
Text File  |  1995-10-22  |  5KB  |  191 lines

  1. # Disassembler
  2.  
  3. import sys
  4. import string
  5.  
  6. def dis():
  7.     tb = sys.last_traceback
  8.     while tb.tb_next: tb = tb.tb_next
  9.     distb(tb)
  10.  
  11. def distb(tb):
  12.     disassemble(tb.tb_frame.f_code, tb.tb_lasti)
  13.  
  14. def disco(co):
  15.     disassemble(co, -1)
  16.  
  17. def disassemble(co, lasti):
  18.     code = co.co_code
  19.     labels = findlabels(code)
  20.     n = len(code)
  21.     i = 0
  22.     while i < n:
  23.         c = code[i]
  24.         op = ord(c)
  25.         if op == SET_LINENO and i > 0: print # Extra blank line
  26.         if i == lasti: print '-->',
  27.         else: print '   ',
  28.         if i in labels: print '>>',
  29.         else: print '  ',
  30.         print string.rjust(`i`, 4),
  31.         print string.ljust(opname[op], 15),
  32.         i = i+1
  33.         if op >= HAVE_ARGUMENT:
  34.             oparg = ord(code[i]) + ord(code[i+1])*256
  35.             i = i+2
  36.             print string.rjust(`oparg`, 5),
  37.             if op in hasconst:
  38.                 print '(' + `co.co_consts[oparg]` + ')',
  39.             elif op in hasname:
  40.                 print '(' + co.co_names[oparg] + ')',
  41.             elif op in hasjrel:
  42.                 print '(to ' + `i + oparg` + ')',
  43.         print
  44.  
  45. def findlabels(code):
  46.     labels = []
  47.     n = len(code)
  48.     i = 0
  49.     while i < n:
  50.         c = code[i]
  51.         op = ord(c)
  52.         i = i+1
  53.         if op >= HAVE_ARGUMENT:
  54.             oparg = ord(code[i]) + ord(code[i+1])*256
  55.             i = i+2
  56.             label = -1
  57.             if op in hasjrel:
  58.                 label = i+oparg
  59.             elif op in hasjabs:
  60.                 label = oparg
  61.             if label >= 0:
  62.                 if label not in labels:
  63.                     labels.append(label)
  64.     return labels
  65.  
  66. hasconst = []
  67. hasname = []
  68. hasjrel = []
  69. hasjabs = []
  70.  
  71. opname = [''] * 256
  72. for op in range(256): opname[op] = '<' + `op` + '>'
  73.  
  74. def def_op(name, op):
  75.     opname[op] = name
  76.  
  77. def name_op(name, op):
  78.     opname[op] = name
  79.     hasname.append(op)
  80.  
  81. def jrel_op(name, op):
  82.     opname[op] = name
  83.     hasjrel.append(op)
  84.  
  85. def jabs_op(name, op):
  86.     opname[op] = name
  87.     hasjabs.append(op)
  88.  
  89. # Instruction opcodes for compiled code
  90.  
  91. def_op('STOP_CODE', 0)
  92. def_op('POP_TOP', 1)
  93. def_op('ROT_TWO', 2)
  94. def_op('ROT_THREE', 3)
  95. def_op('DUP_TOP', 4)
  96.  
  97. def_op('UNARY_POSITIVE', 10)
  98. def_op('UNARY_NEGATIVE', 11)
  99. def_op('UNARY_NOT', 12)
  100. def_op('UNARY_CONVERT', 13)
  101. def_op('UNARY_CALL', 14)
  102. def_op('UNARY_INVERT', 15)
  103.  
  104. def_op('BINARY_MULTIPLY', 20)
  105. def_op('BINARY_DIVIDE', 21)
  106. def_op('BINARY_MODULO', 22)
  107. def_op('BINARY_ADD', 23)
  108. def_op('BINARY_SUBTRACT', 24)
  109. def_op('BINARY_SUBSCR', 25)
  110. def_op('BINARY_CALL', 26)
  111.  
  112. def_op('SLICE+0', 30)
  113. def_op('SLICE+1', 31)
  114. def_op('SLICE+2', 32)
  115. def_op('SLICE+3', 33)
  116.  
  117. def_op('STORE_SLICE+0', 40)
  118. def_op('STORE_SLICE+1', 41)
  119. def_op('STORE_SLICE+2', 42)
  120. def_op('STORE_SLICE+3', 43)
  121.  
  122. def_op('DELETE_SLICE+0', 50)
  123. def_op('DELETE_SLICE+1', 51)
  124. def_op('DELETE_SLICE+2', 52)
  125. def_op('DELETE_SLICE+3', 53)
  126.  
  127. def_op('STORE_SUBSCR', 60)
  128. def_op('DELETE_SUBSCR', 61)
  129.  
  130. def_op('PRINT_EXPR', 70)
  131. def_op('PRINT_ITEM', 71)
  132. def_op('PRINT_NEWLINE', 72)
  133.  
  134. def_op('BREAK_LOOP', 80)
  135. def_op('RAISE_EXCEPTION', 81)
  136. def_op('LOAD_LOCALS', 82)
  137. def_op('RETURN_VALUE', 83)
  138. def_op('LOAD_GLOBALS', 84)
  139. def_op('EXEC_STMT', 85)
  140. def_op('BUILD_FUNCTION', 86)
  141. def_op('POP_BLOCK', 87)
  142. def_op('END_FINALLY', 88)
  143. def_op('BUILD_CLASS', 89)
  144.  
  145. HAVE_ARGUMENT = 90        # Opcodes from here have an argument: 
  146.  
  147. name_op('STORE_NAME', 90)    # Index in name list 
  148. name_op('DELETE_NAME', 91)    # "" 
  149. def_op('UNPACK_TUPLE', 92)    # Number of tuple items 
  150. def_op('UNPACK_LIST', 93)    # Number of list items 
  151. def_op('UNPACK_ARG', 94)    # Number of arguments expected
  152. name_op('STORE_ATTR', 95)    # Index in name list 
  153. name_op('DELETE_ATTR', 96)    # ""
  154. name_op('STORE_GLOBAL', 97)    # ""
  155. name_op('DELETE_GLOBAL', 98)    # ""
  156. name_op('UNPACK_VARARG', 99)    # Minimal number of arguments
  157.  
  158. def_op('LOAD_CONST', 100)    # Index in const list 
  159. hasconst.append(100)
  160. name_op('LOAD_NAME', 101)    # Index in name list 
  161. def_op('BUILD_TUPLE', 102)    # Number of tuple items 
  162. def_op('BUILD_LIST', 103)    # Number of list items 
  163. def_op('BUILD_MAP', 104)    # Always zero for now 
  164. name_op('LOAD_ATTR', 105)    # Index in name list 
  165. def_op('COMPARE_OP', 106)    # Comparison operator 
  166. name_op('IMPORT_NAME', 107)    # Index in name list 
  167. name_op('IMPORT_FROM', 108)    # Index in name list 
  168.  
  169. jrel_op('JUMP_FORWARD', 110)    # Number of bytes to skip 
  170. jrel_op('JUMP_IF_FALSE', 111)    # "" 
  171. jrel_op('JUMP_IF_TRUE', 112)    # "" 
  172. jabs_op('JUMP_ABSOLUTE', 113)    # Target byte offset from beginning of code 
  173. jrel_op('FOR_LOOP', 114)    # Number of bytes to skip 
  174.  
  175. name_op('LOAD_LOCAL', 115)    # Index in name list
  176. name_op('LOAD_GLOBAL', 116)    # Index in name list
  177. def_op('SET_FUNC_ARGS', 117)    # Argcount
  178.  
  179. jrel_op('SETUP_LOOP', 120)    # Distance to target address
  180. jrel_op('SETUP_EXCEPT', 121)    # ""
  181. jrel_op('SETUP_FINALLY', 122)    # ""
  182.  
  183. def_op('RESERVE_FAST', 123)    # Number of local variables
  184. hasconst.append(123)
  185. def_op('LOAD_FAST', 124)    # Local variable number
  186. def_op('STORE_FAST', 125)    # Local variable number
  187. def_op('DELETE_FAST', 126)    # Local variable number
  188.  
  189. def_op('SET_LINENO', 127)    # Current line number
  190. SET_LINENO = 127
  191.